package com.vito.act.tool;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import com.vito.act.model.ActExSaveModel;
import com.vito.act.model.ActExTableColsModel;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.exception.ParamErrorException;
import com.vito.base.model.FtpModel;
import com.vito.base.model.MyHashMap;
import com.vito.base.util.Contants;
import com.vito.base.util.FtpHelper;
import com.vito.base.util.RSATool;
import com.vito.base.util.RSATool.KEYTYPE;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.oa.act.constant.OaActContants;

@Component
public class OaActivitiFormDataTool {
	private final static Logger log = LoggerFactory.getLogger(OaActivitiFormDataTool.class);

	@SuppressWarnings("unchecked")
	public static void generateTabkeKey(Map<String, Object> table, Map<String, Map<String, Object>> data,
			UserModel user) {
		ActExTableColsModel main = (ActExTableColsModel) table.get(Contants.FORM_KEY_MAIN);
		String keyVal = null;
		String tabKey = null;
		Map<String, Object> info = data.get(Contants.FORM_KEY_INFO);
		if (info == null) {
			info = new HashMap<String, Object>();
			data.put(Contants.FORM_KEY_INFO, info);
			keyVal = StringUtil.getUUID();
		} else {
			keyVal = (String) info.get(Contants.FORM_KEY_BUSENESSID);
			if (keyVal == null || "".equals(keyVal)) {
				keyVal = StringUtil.getUUID();
			}
		}
		// 插入公共属性
		info.put(Contants.FORM_KEY_BUSENESSID, keyVal);
		info.put(Contants.FORM_PROCESS_USER_ID, user.getUserId());
		//操作节点
		String nodeId = (String) info.get(Contants.FORM_KEY_NODEID);
		//任务id
		String taskId = (String) info.get(Contants.FORM_KEY_TASKID);
		if(nodeId==null||"".equals(nodeId)){
			nodeId = Contants.FORM_PROCESS_START;
		}
		if (taskId == null || "".equals(taskId)) {
			taskId = Contants.FORM_PROCESS_MAIN_TASKID;
		}
		info.put(Contants.FORM_KEY_TASKID, taskId);
		info.put(Contants.FORM_KEY_NODEID, nodeId);
		if (main != null) {
			tabKey = main.getColName();
			Map<String, Object> mainMap = (Map<String, Object>) data.get(Contants.FORM_KEY_MAIN)
					.get(main.getTableKey());
			if (mainMap != null) {
				mainMap.put(Contants.FORM_KEY_PKNAME, tabKey);
				Map<String, Object> dataMap = (Map<String, Object>) mainMap.get(Contants.FORM_KEY_DATA);
				if (dataMap != null) {
					// 插入主表ID
					dataMap.put(tabKey, keyVal);
				}
			}
		}
		List<ActExTableColsModel> subs = (List<ActExTableColsModel>) table.get(Contants.FORM_KEY_SUBS);
		//有配置字表信息
		if(subs!=null){
			//循环字表的列  检查主键，及外键
			for(ActExTableColsModel sub :subs){
				Map<String,Object> subdata = data.get(Contants.FORM_KEY_SUBS);
				if(subdata==null){
					log.debug("子数据为空");
					return;
				}
				//取出当前表
				Map<String,Object> subsMap = (Map<String,Object>)subdata.get(sub.getTableKey());
				if(subsMap==null){
					log.debug("字表"+sub.getTableKey()+" 数据为空.");
					continue ;
				}
				//取出当前表的数据集
				List<Map<String,Object>> subsData = (List<Map<String, Object>>) subsMap.get(Contants.FORM_KEY_DATA);
				if(subsData==null||subsData.size()==0){
					log.debug("字表"+sub.getTableKey()+"[data] 数据为空.");
					continue ;
				}
				if (Contants.BASE_STATE.equals(sub.getIsFk())) {
					subsMap.put(Contants.FORM_KEY_PKNAME, sub.getColName());
				}
				if (Contants.BASE_STATE.equals(sub.getIsPk())) {
					subsMap.put(OaActContants.FORM_KEY_FKNAME, sub.getColName());
				}
				for (Map<String, Object> subData : subsData) {
					if (Contants.BASE_STATE.equals(sub.getIsPk())) {
						subData.put(sub.getColName(), StringUtil.getUUID());
					} else if (Contants.BASE_STATE.equals(sub.getIsFk())) {
						try {
							Map<String, Object> mainData = null;
							if(data.containsKey(Contants.FORM_KEY_MAIN)){
								mainData = (Map<String, Object>) data.get(Contants.FORM_KEY_MAIN)
									.get(sub.getFkTableKey());
							}
							String fkVal = null;
							if (mainData != null) {
								mainData = (Map<String, Object>) mainData.get(Contants.FORM_KEY_DATA);
								if (mainData != null) {
									fkVal = (String) mainData.get(sub.getFkTableCol());
								}
							}
							if (fkVal == null) {
								fkVal = keyVal;
							}
							subData.put(sub.getColName(), fkVal);
						} catch (NullPointerException e) {
							log.debug("获取数据为空", e);
							data = null;
							return;
						}
					}
				}
			}
		}
	}

	public static void getInsOrUpdSql(Map<String, String> table, Map<String, Object> paramdata, String taskId,
			boolean isMain, ActExSaveModel model) {
		String columns = "";
		String values = "";
		String where = "";
		String operType = table.get(OaActContants.FORM_OPER_TYPE);
		String pkName = table.get(OaActContants.FORM_KEY_PKNAME);
		String fkName = table.get(OaActContants.FORM_KEY_FKNAME);
		String tableName = table.get(OaActContants.FORM_KEY_TABLE_NAME);
		String encrypt = table.get(OaActContants.FORM_ENCRYPT);
		// 新增
		if (Contants.FORM_OPER_INS.equals(operType)) {
			for (Entry<String, Object> entry : paramdata.entrySet()) {
				if (entry.getValue() != null && !entry.getValue().equals("")) {
					columns += entry.getKey() + ",";
					values += "#{p" + model.getIndex() + "},";
					String encryptStr = null;
					if (Contants.BASE_STATE.equals(encrypt)) {
						// 表单加密,主键，外键值不加密
						if (entry.getKey().equals(pkName) || entry.getKey().equals(fkName)) {
							encryptStr = String.valueOf(entry.getValue());
						} else {
							try {
								encryptStr = RSATool.encrypt(KEYTYPE.PUBLIC, String.valueOf(entry.getValue()));
							} catch (Exception e) {
								encryptStr = String.valueOf(entry.getValue());
							}
						}
					} else {
						encryptStr = String.valueOf(entry.getValue());
					}
					model.getParam_map().put("p" + model.getIndex(), encryptStr);
					model.setIndex(model.getIndex() + 1);
				}
			}
			if (!isMain) {
				columns += "task_id,";
				values += "#{p" + model.getIndex() + "},";
				model.getParam_map().put("p" + model.getIndex(), taskId);
				model.setIndex(model.getIndex() + 1);
			}
			if (columns.length() > 0) {
				columns = columns.substring(0, columns.length() - 1);
				values = values.substring(0, values.length() - 1);
			}
			model.getSql().append("insert into " + tableName + "(" + columns + ") values(" + values + ");");
		}
		// 更新
		else if (Contants.FORM_OPER_UPD.equals(operType)) {
			for (Entry<String, Object> entry : paramdata.entrySet()) {
				if (entry.getKey().equals(pkName) || entry.getKey().equals(fkName)) {
					where = entry.getKey() + " = #{p" + model.getIndex() + "}";
					model.getParam_map().put("p" + model.getIndex(), entry.getValue());
				} else {
					columns += " set " + entry.getKey() + "=#{p" + model.getIndex() + "},";
					try {
						model.getParam_map().put("p" + model.getIndex(),
								RSATool.encrypt(KEYTYPE.PUBLIC, String.valueOf(entry.getValue())));
					} catch (Exception e) {
						log.error("审批-taskId:{}======>加密异常", e);
					}
				}
				model.setIndex(model.getIndex() + 1);
			}
			if (!isMain && Validata.notNullOrEmpty(taskId)) {
				where += " and task_id=";
				where += "#{p" + model.getIndex() + "}";
				model.getParam_map().put("p" + model.getIndex(), taskId);
				model.setIndex(model.getIndex() + 1);
			}
			if (columns.length() > 0) {
				columns = columns.substring(0, columns.length() - 1);
			}
			model.getSql().append("update " + tableName + columns + " where " + where + ";");

		}
	}
	public static Map<String, String> getSelectSql(String tableName,String tableWhere,List<MyHashMap<String, String>> cols,String bussId,String taskId){
		if(Validata.isNullOrEmpty(bussId)){
			return null;
		}
		if(cols==null||cols.size()==0){
			return null;
		}
		if(Validata.isNullOrEmpty(tableName)){
			return null;
		}
		if(Validata.isNullOrEmpty(tableWhere)){
			return null;
		}

		StringBuffer sql = new StringBuffer();
		Map<String, String> params = new HashMap<String, String>();
		sql.append("select ");
		for (int i = 0; i < cols.size(); i++) {
			// if((!Validata.isNullOrEmpty(cols.get(i).get("is_pk"))&&Contants.BASE_STATE.equals(cols.get(i).get("is_pk")))
			// ||!Validata.isNullOrEmpty(cols.get(i).get("is_fk"))&&Contants.BASE_STATE.equals(cols.get(i).get("is_fk"))){
			// continue;
			// }
			if (!Validata.isNullOrEmpty(cols.get(i).get("is_fk"))
					&& Contants.BASE_STATE.equals(cols.get(i).get("is_fk"))) {
				continue;
			}
			if (Validata.notNullOrEmpty(taskId) && (Validata.notNullOrEmpty(cols.get(i).get("is_pk"))
					&& Contants.BASE_STATE.equals(cols.get(i).get("is_pk")))) {
				continue;
			}
			String fun_name = cols.get(i).get("fun_name");
			String col_name = cols.get(i).get("col_name");

			if (Validata.isNullOrEmpty(fun_name)) {
				sql.append(col_name);
			} else {
				fun_name = fun_name.replaceAll("[?]", col_name);
				sql.append(fun_name + " as " + col_name);
			}
			sql.append(",");
		}
		String sqlstr = sql.substring(0, sql.length() - 1);
		StringBuffer resSql = new StringBuffer();
		resSql.append(sqlstr);
		resSql.append(" from " + Contants.TABLE_FIRST_NAME + tableName + " where " + tableWhere + " = #{p1}");
		params.put("p1", bussId);
		if (!Validata.isNullOrEmpty(taskId)) {
			resSql.append(" and task_id = #{p2}");
			params.put("p2", taskId);
		}
		params.put("sql", resSql.toString());
		return params;
	}

	/**
	 * 数据解密
	 * 
	 * @param data
	 *            { tab:{}, data:[{}], cols:{{}} }
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> decryptData(Map<String, Object> data) {
		String encrypt = null;
		String pkName = "";
		String fkName = "";
		if (data.containsKey(Contants.FORM_KEY_TAB)) {
			Map<String, String> tabInfo = (Map<String, String>) data.get(Contants.FORM_KEY_TAB);
			pkName = tabInfo.get(OaActContants.FORM_KEY_PKNAME.toLowerCase());
			fkName = tabInfo.get(OaActContants.FORM_KEY_FKNAME.toLowerCase());
			if (tabInfo.containsKey(OaActContants.FORM_ENCRYPT)) {
				encrypt = tabInfo.get(OaActContants.FORM_ENCRYPT);
			}
			if (Validata.notNullOrEmpty(encrypt) && Contants.BASE_STATE.equals(encrypt)) {
				List<Map<String, Object>> formList = (List<Map<String, Object>>) data.get(Contants.FORM_KEY_DATA);
				if (!formList.isEmpty()) {
					for (Map<String, Object> formMap : formList) {
						for (Entry<String, Object> entry : formMap.entrySet()) {
							String key = String.valueOf(entry.getKey());
							String val = String.valueOf(entry.getValue());
							if (!key.equals(pkName) && !key.equals(fkName)) {
								try {
									entry.setValue(RSATool.decrypt(KEYTYPE.PRIVATE, val));
								} catch (Exception e) {
									continue;
								}
							}
						}
					}
				}
			}
		}
		return data;
	}

	/**
	 * 从FTP下载完结流程表单数据
	 * 
	 * @param ftpModel
	 * @return
	 * @throws IOException
	 * @throws ParamErrorException
	 */

	@Cacheable(value = OaActContants.CACHE_ACT_OVER_INFO, key = "#root.method.name+'_'+#p0.getFileNewName()")
	public StringBuffer readFileStream(FtpModel ftpModel){
		StringBuffer sb = new StringBuffer();
		InputStream inStream = null;
		try {
			inStream = new FtpHelper().readFileStream(ftpModel);
		} catch (Exception e) {
			return null;
		}
		if (null != inStream) {
			try {
				BufferedInputStream bis = new BufferedInputStream(inStream);
				BufferedReader reader = new BufferedReader(new InputStreamReader(bis,"UTF-8"));
				while (reader.ready()) {
					sb.append((char) reader.read());
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					inStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return sb;
	}

}
